﻿namespace Oddo.Concept.Crm.Common.Interfaces
{
    using System;
    using System.Linq;
    using System.Linq.Expressions;
    using Oddo.Concept.Crm.Common.Models;

    /// <summary>
    /// Contrat d'interface du gestionnaire d'accès aux données
    /// </summary>
    public interface IDataAccess
    {
    }

    /// <summary>
    /// Contrat d'interface du gestionnaire d'accès aux données fortement typé
    /// </summary>
    /// <typeparam name="T">Le type d'une classe implémentant l'interface IBusinessModel</typeparam>
    public interface IDataAccess<T> : IDataAccess
        where T : IBusinessModel
    {
        /// <summary>
        /// Construit une requete de selection
        /// </summary>
        IQueryable<T> Query();
        /// <summary>
        /// Construit une requete de selection
        /// </summary>
        /// <param name="predicate">Expression lambda utilisée comme critère de sélection</param>
        /// <returns>Une instance d'IQueryable de type T representant la requete de sélection</returns>
        IQueryable<T> Query(Expression<Func<T, bool>> predicate);
        /// <summary>
        /// Sauvegarde une instance de type T en base
        /// </summary>
        /// <param name="value">Une instance de type T à sauvegarder</param>
        /// <returns>L'instance de type T sauvegardée</returns>
        T Save(T value);
        /// <summary>
        /// Supprime une instance de type T de la base
        /// </summary>
        /// <param name="value">Une instance de type T à supprimer</param>
        void Delete(T value);
    }
    /// <summary>
    /// Classe de base du gestionnaire d'accès aux données fortement typé
    /// </summary>
    /// <typeparam name="T">Le type d'une classe implémentant l'interface IBusinessModel</typeparam>
    public abstract class DataAccessBase<T> : IDataAccess<T>
        where T : IBusinessModel
    {
        public abstract IQueryable<T> Query();
        public abstract IQueryable<T> Query(Expression<Func<T, bool>> predicate);
        public abstract T Save(T value);
        public abstract void Delete(T value);
    }
}